﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using Epic.ComponentServices.Converters;

namespace EpicFail.Core.Test
{
    [TestClass]
    public class EnumConverterTest
    {
        #region 1

        enum I1 : sbyte
        {
            Zero,
            One,
            Two,
            All = -1
        }
        [Flags]
        enum FI1 : sbyte
        {
            Zero,
            One,
            Two,
            All = -1
        }
        enum I1S : sbyte
        {
            One = 1,
            Two,
            All = -1
        }
        [Flags]
        enum FI1S : sbyte
        {
            One = 1,
            Two,
            All = -1
        }

        enum U1 : byte
        {
            Zero,
            One,
            Two,
        }
        [Flags]
        enum FU1 : byte
        {
            Zero,
            One,
            Two,
        }
        enum U1S : byte
        {
            One = 1,
            Two,
        }
        [Flags]
        enum FU1S : byte
        {
            One = 1,
            Two,
        }

        #endregion

        #region 2

        enum I2 : short
        {
            Zero,
            One,
            Two,
            All = -1
        }
        [Flags]
        enum FI2 : short
        {
            Zero,
            One,
            Two,
            All = -1
        }
        enum I2S : short
        {
            One = 1,
            Two,
            All = -1
        }
        [Flags]
        enum FI2S : short
        {
            One = 1,
            Two,
            All = -1
        }

        enum U2 : ushort
        {
            Zero,
            One,
            Two,
        }
        [Flags]
        enum FU2 : ushort
        {
            Zero,
            One,
            Two,
        }
        enum U2S : ushort
        {
            One = 1,
            Two,
        }
        [Flags]
        enum FU2S : ushort
        {
            One = 1,
            Two,
        }

        #endregion

        #region 4

        enum I4 : short
        {
            Zero,
            One,
            Two,
            All = -1
        }
        [Flags]
        enum FI4 : short
        {
            Zero,
            One,
            Two,
            All = -1
        }
        enum I4S : short
        {
            One = 1,
            Two,
            All = -1
        }
        [Flags]
        enum FI4S : short
        {
            One = 1,
            Two,
            All = -1
        }

        enum U4 : ushort
        {
            Zero,
            One,
            Two,
        }
        [Flags]
        enum FU4 : ushort
        {
            Zero,
            One,
            Two,
        }
        enum U4S : ushort
        {
            One = 1,
            Two,
        }
        [Flags]
        enum FU4S : ushort
        {
            One = 1,
            Two,
        }

        #endregion

        #region 8

        enum I8 : short
        {
            Zero,
            One,
            Two,
            All = -1
        }
        [Flags]
        enum FI8 : short
        {
            Zero,
            One,
            Two,
            All = -1
        }
        enum I8S : short
        {
            One = 1,
            Two,
            All = -1
        }
        [Flags]
        enum FI8S : short
        {
            One = 1,
            Two,
            All = -1
        }

        enum U8 : ushort
        {
            Zero,
            One,
            Two,
        }
        [Flags]
        enum FU8 : ushort
        {
            Zero,
            One,
            Two,
        }
        enum U8S : ushort
        {
            One = 1,
            Two,
        }
        [Flags]
        enum FU8S : ushort
        {
            One = 1,
            Two,
        }

        #endregion

        [TestMethod]
        public void TestEnum1()
        {
            {
                var c = new EnhancedEnumConverter(typeof(I1), " | ");
                Assert.AreEqual(I1.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(I1.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(I1.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(I1.Zero));

                Assert.AreEqual(I1.One, c.ConvertFromString("One"));
                Assert.AreEqual(I1.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(I1.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(I1.One));

                Assert.AreEqual(I1.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(I1.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(I1.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(I1.Two));

                Assert.AreEqual(I1.All, c.ConvertFromString("All"));
                Assert.AreEqual(I1.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(I1.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(I1.All));

                Assert.AreEqual((I1)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((I1)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((I1)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((I1)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FI1), " | ");
                Assert.AreEqual(FI1.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(FI1.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(FI1.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(FI1.Zero));

                Assert.AreEqual(FI1.One, c.ConvertFromString("One"));
                Assert.AreEqual(FI1.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FI1.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FI1.One));

                Assert.AreEqual(FI1.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FI1.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FI1.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FI1.Two));

                Assert.AreEqual(FI1.All, c.ConvertFromString("All"));
                Assert.AreEqual(FI1.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(FI1.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(FI1.All));

                Assert.AreEqual((FI1)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FI1)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FI1)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FI1)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FI1)4));
                Assert.IsFalse(c.IsValid(4));

                Assert.AreEqual((FI1)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((FI1)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(I1S), " | ");
                Assert.AreEqual((I1S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((I1S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(I1S.One, c.ConvertFromString("One"));
                Assert.AreEqual(I1S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(I1S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(I1S.One));

                Assert.AreEqual(I1S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(I1S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(I1S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(I1S.Two));

                Assert.AreEqual(I1S.All, c.ConvertFromString("All"));
                Assert.AreEqual(I1S.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(I1S.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(I1S.All));

                Assert.AreEqual((I1S)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((I1S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((I1S)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((I1S)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FI1S), " | ");
                Assert.AreEqual((FI1S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((FI1S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(FI1S.One, c.ConvertFromString("One"));
                Assert.AreEqual(FI1S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FI1S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FI1S.One));

                Assert.AreEqual(FI1S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FI1S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FI1S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FI1S.Two));

                Assert.AreEqual(FI1S.All, c.ConvertFromString("All"));
                Assert.AreEqual(FI1S.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(FI1S.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(FI1S.All));

                Assert.AreEqual((FI1S)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FI1S)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FI1S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FI1S)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FI1S)4));
                Assert.IsFalse(c.IsValid(4));

                Assert.AreEqual((FI1S)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((FI1S)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }

            {
                var c = new EnhancedEnumConverter(typeof(U1), " | ");
                Assert.AreEqual(U1.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(U1.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(U1.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(U1.Zero));

                Assert.AreEqual(U1.One, c.ConvertFromString("One"));
                Assert.AreEqual(U1.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(U1.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(U1.One));

                Assert.AreEqual(U1.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(U1.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(U1.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(U1.Two));

                Assert.AreEqual((U1)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((U1)3));
                Assert.IsFalse(c.IsValid(3));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FU1), " | ");
                Assert.AreEqual(FU1.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(FU1.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(FU1.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(FU1.Zero));

                Assert.AreEqual(FU1.One, c.ConvertFromString("One"));
                Assert.AreEqual(FU1.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FU1.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FU1.One));

                Assert.AreEqual(FU1.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FU1.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FU1.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FU1.Two));

                Assert.AreEqual((FU1)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FU1)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FU1)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FU1)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FU1)4));
                Assert.IsFalse(c.IsValid(4));
            }
            {
                var c = new EnhancedEnumConverter(typeof(U1S), " | ");
                Assert.AreEqual((U1S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((U1S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(U1S.One, c.ConvertFromString("One"));
                Assert.AreEqual(U1S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(U1S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(U1S.One));

                Assert.AreEqual(U1S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(U1S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(U1S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(U1S.Two));

                Assert.AreEqual((U1S)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((U1S)3));
                Assert.IsFalse(c.IsValid(3));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FU1S), " | ");
                Assert.AreEqual((FU1S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((FU1S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(FU1S.One, c.ConvertFromString("One"));
                Assert.AreEqual(FU1S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FU1S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FU1S.One));

                Assert.AreEqual(FU1S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FU1S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FU1S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FU1S.Two));

                Assert.AreEqual((FU1S)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FU1S)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FU1S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FU1S)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FU1S)4));
                Assert.IsFalse(c.IsValid(4));
            }
        }

        [TestMethod]
        public void TestEnum2()
        {
            {
                var c = new EnhancedEnumConverter(typeof(I2), " | ");
                Assert.AreEqual(I2.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(I2.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(I2.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(I2.Zero));

                Assert.AreEqual(I2.One, c.ConvertFromString("One"));
                Assert.AreEqual(I2.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(I2.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(I2.One));

                Assert.AreEqual(I2.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(I2.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(I2.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(I2.Two));

                Assert.AreEqual(I2.All, c.ConvertFromString("All"));
                Assert.AreEqual(I2.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(I2.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(I2.All));

                Assert.AreEqual((I2)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((I2)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((I2)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((I2)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FI2), " | ");
                Assert.AreEqual(FI2.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(FI2.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(FI2.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(FI2.Zero));

                Assert.AreEqual(FI2.One, c.ConvertFromString("One"));
                Assert.AreEqual(FI2.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FI2.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FI2.One));

                Assert.AreEqual(FI2.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FI2.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FI2.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FI2.Two));

                Assert.AreEqual(FI2.All, c.ConvertFromString("All"));
                Assert.AreEqual(FI2.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(FI2.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(FI2.All));

                Assert.AreEqual((FI2)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FI2)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FI2)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FI2)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FI2)4));
                Assert.IsFalse(c.IsValid(4));

                Assert.AreEqual((FI2)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((FI2)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(I2S), " | ");
                Assert.AreEqual((I2S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((I2S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(I2S.One, c.ConvertFromString("One"));
                Assert.AreEqual(I2S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(I2S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(I2S.One));

                Assert.AreEqual(I2S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(I2S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(I2S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(I2S.Two));

                Assert.AreEqual(I2S.All, c.ConvertFromString("All"));
                Assert.AreEqual(I2S.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(I2S.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(I2S.All));

                Assert.AreEqual((I2S)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((I2S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((I2S)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((I2S)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FI2S), " | ");
                Assert.AreEqual((FI2S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((FI2S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(FI2S.One, c.ConvertFromString("One"));
                Assert.AreEqual(FI2S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FI2S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FI2S.One));

                Assert.AreEqual(FI2S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FI2S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FI2S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FI2S.Two));

                Assert.AreEqual(FI2S.All, c.ConvertFromString("All"));
                Assert.AreEqual(FI2S.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(FI2S.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(FI2S.All));

                Assert.AreEqual((FI2S)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FI2S)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FI2S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FI2S)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FI2S)4));
                Assert.IsFalse(c.IsValid(4));

                Assert.AreEqual((FI2S)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((FI2S)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }

            {
                var c = new EnhancedEnumConverter(typeof(U2), " | ");
                Assert.AreEqual(U2.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(U2.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(U2.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(U2.Zero));

                Assert.AreEqual(U2.One, c.ConvertFromString("One"));
                Assert.AreEqual(U2.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(U2.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(U2.One));

                Assert.AreEqual(U2.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(U2.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(U2.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(U2.Two));

                Assert.AreEqual((U2)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((U2)3));
                Assert.IsFalse(c.IsValid(3));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FU2), " | ");
                Assert.AreEqual(FU2.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(FU2.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(FU2.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(FU2.Zero));

                Assert.AreEqual(FU2.One, c.ConvertFromString("One"));
                Assert.AreEqual(FU2.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FU2.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FU2.One));

                Assert.AreEqual(FU2.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FU2.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FU2.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FU2.Two));

                Assert.AreEqual((FU2)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FU2)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FU2)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FU2)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FU2)4));
                Assert.IsFalse(c.IsValid(4));
            }
            {
                var c = new EnhancedEnumConverter(typeof(U2S), " | ");
                Assert.AreEqual((U2S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((U2S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(U2S.One, c.ConvertFromString("One"));
                Assert.AreEqual(U2S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(U2S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(U2S.One));

                Assert.AreEqual(U2S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(U2S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(U2S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(U2S.Two));

                Assert.AreEqual((U2S)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((U2S)3));
                Assert.IsFalse(c.IsValid(3));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FU2S), " | ");
                Assert.AreEqual((FU2S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((FU2S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(FU2S.One, c.ConvertFromString("One"));
                Assert.AreEqual(FU2S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FU2S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FU2S.One));

                Assert.AreEqual(FU2S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FU2S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FU2S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FU2S.Two));

                Assert.AreEqual((FU2S)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FU2S)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FU2S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FU2S)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FU2S)4));
                Assert.IsFalse(c.IsValid(4));
            }
        }

        [TestMethod]
        public void TestEnum4()
        {
            {
                var c = new EnhancedEnumConverter(typeof(I4), " | ");
                Assert.AreEqual(I4.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(I4.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(I4.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(I4.Zero));

                Assert.AreEqual(I4.One, c.ConvertFromString("One"));
                Assert.AreEqual(I4.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(I4.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(I4.One));

                Assert.AreEqual(I4.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(I4.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(I4.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(I4.Two));

                Assert.AreEqual(I4.All, c.ConvertFromString("All"));
                Assert.AreEqual(I4.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(I4.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(I4.All));

                Assert.AreEqual((I4)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((I4)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((I4)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((I4)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FI4), " | ");
                Assert.AreEqual(FI4.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(FI4.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(FI4.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(FI4.Zero));

                Assert.AreEqual(FI4.One, c.ConvertFromString("One"));
                Assert.AreEqual(FI4.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FI4.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FI4.One));

                Assert.AreEqual(FI4.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FI4.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FI4.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FI4.Two));

                Assert.AreEqual(FI4.All, c.ConvertFromString("All"));
                Assert.AreEqual(FI4.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(FI4.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(FI4.All));

                Assert.AreEqual((FI4)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FI4)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FI4)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FI4)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FI4)4));
                Assert.IsFalse(c.IsValid(4));

                Assert.AreEqual((FI4)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((FI4)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(I4S), " | ");
                Assert.AreEqual((I4S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((I4S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(I4S.One, c.ConvertFromString("One"));
                Assert.AreEqual(I4S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(I4S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(I4S.One));

                Assert.AreEqual(I4S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(I4S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(I4S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(I4S.Two));

                Assert.AreEqual(I4S.All, c.ConvertFromString("All"));
                Assert.AreEqual(I4S.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(I4S.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(I4S.All));

                Assert.AreEqual((I4S)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((I4S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((I4S)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((I4S)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FI4S), " | ");
                Assert.AreEqual((FI4S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((FI4S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(FI4S.One, c.ConvertFromString("One"));
                Assert.AreEqual(FI4S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FI4S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FI4S.One));

                Assert.AreEqual(FI4S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FI4S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FI4S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FI4S.Two));

                Assert.AreEqual(FI4S.All, c.ConvertFromString("All"));
                Assert.AreEqual(FI4S.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(FI4S.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(FI4S.All));

                Assert.AreEqual((FI4S)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FI4S)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FI4S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FI4S)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FI4S)4));
                Assert.IsFalse(c.IsValid(4));

                Assert.AreEqual((FI4S)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((FI4S)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }

            {
                var c = new EnhancedEnumConverter(typeof(U4), " | ");
                Assert.AreEqual(U4.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(U4.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(U4.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(U4.Zero));

                Assert.AreEqual(U4.One, c.ConvertFromString("One"));
                Assert.AreEqual(U4.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(U4.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(U4.One));

                Assert.AreEqual(U4.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(U4.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(U4.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(U4.Two));

                Assert.AreEqual((U4)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((U4)3));
                Assert.IsFalse(c.IsValid(3));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FU4), " | ");
                Assert.AreEqual(FU4.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(FU4.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(FU4.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(FU4.Zero));

                Assert.AreEqual(FU4.One, c.ConvertFromString("One"));
                Assert.AreEqual(FU4.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FU4.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FU4.One));

                Assert.AreEqual(FU4.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FU4.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FU4.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FU4.Two));

                Assert.AreEqual((FU4)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FU4)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FU4)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FU4)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FU4)4));
                Assert.IsFalse(c.IsValid(4));
            }
            {
                var c = new EnhancedEnumConverter(typeof(U4S), " | ");
                Assert.AreEqual((U4S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((U4S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(U4S.One, c.ConvertFromString("One"));
                Assert.AreEqual(U4S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(U4S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(U4S.One));

                Assert.AreEqual(U4S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(U4S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(U4S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(U4S.Two));

                Assert.AreEqual((U4S)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((U4S)3));
                Assert.IsFalse(c.IsValid(3));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FU4S), " | ");
                Assert.AreEqual((FU4S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((FU4S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(FU4S.One, c.ConvertFromString("One"));
                Assert.AreEqual(FU4S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FU4S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FU4S.One));

                Assert.AreEqual(FU4S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FU4S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FU4S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FU4S.Two));

                Assert.AreEqual((FU4S)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FU4S)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FU4S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FU4S)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FU4S)4));
                Assert.IsFalse(c.IsValid(4));
            }
        }

        [TestMethod]
        public void TestEnum8()
        {
            {
                var c = new EnhancedEnumConverter(typeof(I8), " | ");
                Assert.AreEqual(I8.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(I8.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(I8.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(I8.Zero));

                Assert.AreEqual(I8.One, c.ConvertFromString("One"));
                Assert.AreEqual(I8.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(I8.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(I8.One));

                Assert.AreEqual(I8.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(I8.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(I8.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(I8.Two));

                Assert.AreEqual(I8.All, c.ConvertFromString("All"));
                Assert.AreEqual(I8.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(I8.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(I8.All));

                Assert.AreEqual((I8)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((I8)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((I8)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((I8)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FI8), " | ");
                Assert.AreEqual(FI8.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(FI8.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(FI8.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(FI8.Zero));

                Assert.AreEqual(FI8.One, c.ConvertFromString("One"));
                Assert.AreEqual(FI8.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FI8.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FI8.One));

                Assert.AreEqual(FI8.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FI8.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FI8.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FI8.Two));

                Assert.AreEqual(FI8.All, c.ConvertFromString("All"));
                Assert.AreEqual(FI8.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(FI8.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(FI8.All));

                Assert.AreEqual((FI8)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FI8)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FI8)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FI8)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FI8)4));
                Assert.IsFalse(c.IsValid(4));

                Assert.AreEqual((FI8)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((FI8)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(I8S), " | ");
                Assert.AreEqual((I8S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((I8S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(I8S.One, c.ConvertFromString("One"));
                Assert.AreEqual(I8S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(I8S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(I8S.One));

                Assert.AreEqual(I8S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(I8S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(I8S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(I8S.Two));

                Assert.AreEqual(I8S.All, c.ConvertFromString("All"));
                Assert.AreEqual(I8S.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(I8S.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(I8S.All));

                Assert.AreEqual((I8S)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((I8S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((I8S)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((I8S)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FI8S), " | ");
                Assert.AreEqual((FI8S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((FI8S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(FI8S.One, c.ConvertFromString("One"));
                Assert.AreEqual(FI8S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FI8S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FI8S.One));

                Assert.AreEqual(FI8S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FI8S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FI8S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FI8S.Two));

                Assert.AreEqual(FI8S.All, c.ConvertFromString("All"));
                Assert.AreEqual(FI8S.All, c.ConvertFromString("-1"));
                Assert.AreEqual("All", c.ConvertToString(FI8S.All));
                Assert.IsTrue(c.IsValid(-1));
                Assert.IsTrue(c.IsValid("All"));
                Assert.IsTrue(c.IsValid(FI8S.All));

                Assert.AreEqual((FI8S)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FI8S)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FI8S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FI8S)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FI8S)4));
                Assert.IsFalse(c.IsValid(4));

                Assert.AreEqual((FI8S)(-2), c.ConvertFromString("-2"));
                Assert.AreEqual("-2", c.ConvertToString((FI8S)(-2)));
                Assert.IsFalse(c.IsValid(-2));
            }

            {
                var c = new EnhancedEnumConverter(typeof(U8), " | ");
                Assert.AreEqual(U8.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(U8.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(U8.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(U8.Zero));

                Assert.AreEqual(U8.One, c.ConvertFromString("One"));
                Assert.AreEqual(U8.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(U8.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(U8.One));

                Assert.AreEqual(U8.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(U8.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(U8.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(U8.Two));

                Assert.AreEqual((U8)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((U8)3));
                Assert.IsFalse(c.IsValid(3));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FU8), " | ");
                Assert.AreEqual(FU8.Zero, c.ConvertFromString("Zero"));
                Assert.AreEqual(FU8.Zero, c.ConvertFromString("0"));
                Assert.AreEqual("Zero", c.ConvertToString(FU8.Zero));
                Assert.IsTrue(c.IsValid(0));
                Assert.IsTrue(c.IsValid("Zero"));
                Assert.IsTrue(c.IsValid(FU8.Zero));

                Assert.AreEqual(FU8.One, c.ConvertFromString("One"));
                Assert.AreEqual(FU8.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FU8.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FU8.One));

                Assert.AreEqual(FU8.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FU8.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FU8.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FU8.Two));

                Assert.AreEqual((FU8)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FU8)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FU8)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FU8)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FU8)4));
                Assert.IsFalse(c.IsValid(4));
            }
            {
                var c = new EnhancedEnumConverter(typeof(U8S), " | ");
                Assert.AreEqual((U8S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((U8S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(U8S.One, c.ConvertFromString("One"));
                Assert.AreEqual(U8S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(U8S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(U8S.One));

                Assert.AreEqual(U8S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(U8S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(U8S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(U8S.Two));

                Assert.AreEqual((U8S)3, c.ConvertFromString("3"));
                Assert.AreEqual("3", c.ConvertToString((U8S)3));
                Assert.IsFalse(c.IsValid(3));
            }
            {
                var c = new EnhancedEnumConverter(typeof(FU8S), " | ");
                Assert.AreEqual((FU8S)0, c.ConvertFromString("0"));
                Assert.AreEqual("0", c.ConvertToString((FU8S)0));
                Assert.IsFalse(c.IsValid(0));

                Assert.AreEqual(FU8S.One, c.ConvertFromString("One"));
                Assert.AreEqual(FU8S.One, c.ConvertFromString("1"));
                Assert.AreEqual("One", c.ConvertToString(FU8S.One));
                Assert.IsTrue(c.IsValid(1));
                Assert.IsTrue(c.IsValid("One"));
                Assert.IsTrue(c.IsValid(FU8S.One));

                Assert.AreEqual(FU8S.Two, c.ConvertFromString("Two"));
                Assert.AreEqual(FU8S.Two, c.ConvertFromString("2"));
                Assert.AreEqual("Two", c.ConvertToString(FU8S.Two));
                Assert.IsTrue(c.IsValid(2));
                Assert.IsTrue(c.IsValid("Two"));
                Assert.IsTrue(c.IsValid(FU8S.Two));

                Assert.AreEqual((FU8S)3, c.ConvertFromString("One|Two"));
                Assert.AreEqual((FU8S)3, c.ConvertFromString("3"));
                Assert.AreEqual("One | Two", c.ConvertToString((FU8S)3));
                Assert.IsFalse(c.IsValid(3));

                Assert.AreEqual((FU8S)4, c.ConvertFromString("4"));
                Assert.AreEqual("4", c.ConvertToString((FU8S)4));
                Assert.IsFalse(c.IsValid(4));
            }
        }
    }
}
